﻿// ------------------------------------------------------------------------------------------------
//  <copyright file="BasicContent.cs" company="Iveely">
//    Copyright (c) Iveely Liu.  All rights reserved.
//  </copyright>
//  
//  <Create Time>
//    03/02/2013 21:59 
//  </Create Time>
//  
//  <contact owner>
//    liufanping@iveely.com 
//  </contact owner>
//  -----------------------------------------------------------------------------------------------

#region

using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Text;

#endregion

namespace IveelySE.Spider
{
    /// <summary>
    ///   信息处理类
    /// </summary>
    public class BasicContent : IDisposable
    {
        /// <summary>
        ///   HTML类型
        /// </summary>
        private static readonly ReadOnlyCollection<string> _HtmlMimeTypes = new ReadOnlyCollection<string>(new[]
                                                                                                               {
                                                                                                                   "application/xhtml+xml"
                                                                                                                   ,
                                                                                                                   "text/html"
                                                                                                                   ,
                                                                                                               });

        /// <summary>
        ///   XML类型
        /// </summary>
        private static readonly ReadOnlyCollection<string> _XmlMimeTypes = new ReadOnlyCollection<string>(new[]
                                                                                                              {
                                                                                                                  "text/xml"
                                                                                                              });

        /// <summary>
        ///   CSS类型
        /// </summary>
        private static readonly ReadOnlyCollection<string> _CssMimeTypes = new ReadOnlyCollection<string>(new[]
                                                                                                              {
                                                                                                                  "text/css"
                                                                                                              });

        /// <summary>
        ///   内存流
        /// </summary>
        private readonly MemoryStream _Stream = new MemoryStream();

        /// <summary>
        ///   一般内容处理模式
        /// </summary>
        /// <param name="requestUrl"> 请求的URL </param>
        /// <param name="referrerUrl"> 引用的URL </param>
        /// <param name="webResponse"> 请求URL的响应结果 </param>
        public BasicContent(Uri requestUrl, Uri referrerUrl, HttpWebResponse webResponse)
        {
            //如果请求URL为空
            if(requestUrl == null)
            {
                throw new ArgumentNullException("requestUrl 不能为空!");
            }
            //如果请求响应为空
            if(webResponse == null)
            {
                throw new ArgumentNullException("webResponse 不能为空!");
            }
            RequestUrl = requestUrl;
            ReferrerUrl = referrerUrl;
            ResponseUrl = webResponse.ResponseUri;
            MimeType = GetMimeType(webResponse);
            this.CharSet = webResponse.CharacterSet;
            using(var stream = webResponse.GetResponseStream())
            {
                stream.CopyTo(_Stream);
            }
            _Stream.Position = 0;
        }

        /// <summary>
        ///   页面信息编码
        /// </summary>
        private string CharSet { get; set; }

        /// <summary>
        ///   HTML类型
        /// </summary>
        public static ReadOnlyCollection<string> HtmlMimeTypes
        {
            get { return _HtmlMimeTypes; }
        }

        /// <summary>
        ///   XML类型
        /// </summary>
        public static ReadOnlyCollection<string> XmlMimeTypes
        {
            get { return _XmlMimeTypes; }
        }

        public static ReadOnlyCollection<string> CssMimeTypes
        {
            get { return _CssMimeTypes; }
        }

        /// <summary>
        ///   引用链接
        /// </summary>
        public Uri ReferrerUrl { get; protected set; }

        /// <summary>
        ///   请求链接
        /// </summary>
        public Uri RequestUrl { get; protected set; }

        /// <summary>
        ///   响应链接
        /// </summary>
        public Uri ResponseUrl { get; protected set; }

        /// <summary>
        ///   媒体类型
        /// </summary>
        public string MimeType { get; protected set; }

        protected MemoryStream Stream
        {
            get { return _Stream; }
        }

        /// <summary>
        ///   文件大小
        /// </summary>
        public virtual long Size
        {
            get { return _Stream.Length; }
        }

        /// <summary>
        ///   文本内容
        /// </summary>
        public virtual string Text
        {
            get
            {
                return Encoding.GetEncoding(this.CharSet).GetString(_Stream.ToArray());
                // Encoding.UTF8.GetString(_Stream.ToArray());
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);

            GC.SuppressFinalize(this);
        }

        #endregion

        /// <summary>
        ///   回去媒体类型
        /// </summary>
        /// <param name="response"> Web请求的响应 </param>
        /// <returns> </returns>
        public static string GetMimeType(WebResponse response)
        {
            //标头
            var contentType = response.Headers[HttpResponseHeader.ContentType];
            //媒体类型
            var mimeType = contentType.Split(';')[0];
            //返回
            return mimeType;
        }

        /// <summary>
        ///   媒体标题
        /// </summary>
        /// <returns> </returns>
        public virtual string GetTitle()
        {
            return "";
        }

        /// <summary>
        ///   正文
        /// </summary>
        /// <returns> </returns>
        public virtual string GetContent()
        {
            return "";
        }

        /// <summary>
        ///   是否是HTML类型
        /// </summary>
        /// <param name="mimeType"> </param>
        /// <returns> True为是HTML类型 </returns>
        public static bool IsHtml(string mimeType)
        {
            return HtmlMimeTypes.Contains(mimeType);
        }

        /// <summary>
        ///   是否是XML类型
        /// </summary>
        /// <param name="mimeType"> </param>
        /// <returns> </returns>
        public static bool IsXml(string mimeType)
        {
            return XmlMimeTypes.Contains(mimeType);
        }

        /// <summary>
        ///   是否是CSS类型
        /// </summary>
        /// <param name="mimeType"> </param>
        /// <returns> </returns>
        public static bool IsCss(string mimeType)
        {
            return CssMimeTypes.Contains(mimeType);
        }

        /// <summary>
        ///   是否是HTML类型
        /// </summary>
        /// <returns> </returns>
        public bool IsHtml()
        {
            return IsHtml(MimeType);
        }

        ///<summary>
        ///  是否是XML类型
        ///</summary>
        ///<returns> </returns>
        public bool IsXml()
        {
            return IsXml(MimeType);
        }

        /// <summary>
        ///   是否是CSS类型
        /// </summary>
        /// <returns> </returns>
        public bool IsCss()
        {
            return IsCss(MimeType);
        }

        public virtual void Save(Stream stream)
        {
            _Stream.Position = 0;
            _Stream.CopyTo(stream);
        }

        protected virtual void Dispose(bool disposing)
        {
            if(disposing)
            {
                _Stream.Dispose();
            }
        }
    }
}